/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package edu.uoc.tfc.exuoc.controladors;

import edu.uoc.tfc.exuoc.config.Config;
import edu.uoc.tfc.exuoc.model.Item;
import edu.uoc.tfc.exuoc.model.InterfaceItem;
import edu.uoc.tfc.exuoc.errors.NoExisteixException;
import edu.uoc.tfc.exuoc.errors.BuitException;
import java.io.UnsupportedEncodingException;
import edu.uoc.tfc.exuoc.utils.seguretat.InjeccioCodi;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.hibernate.HibernateException;
import java.util.Iterator;
import edu.uoc.tfc.exuoc.utils.Eines;
/**
 * Classe que gestionarà la persistència mitjançant la classe
 * GestorBDD (genèrica)
 *
 * @author emoreno
 */
public class ItemsDAO {
    private GestorBDD gd=new GestorBDD();
    private GestorLogs  log=GestorLogs .getLogger(this.getClass().getName());

    protected ItemsDAO(){
        super();
    }

    public void tancarConnexio() {
        //04-01-2012:throws HibernateException{
        gd.close();
        gd=null;
    }



    public Long afegirItem(InterfaceItem item) throws HibernateException, BuitException{
        Long id=-1L;

        try {
            //gd.begin();
            id=gd.afegir(item);
        }catch (HibernateException e){
            log.error("No s'ha pogut afegir l'ítem ({})  ",item.getClass().getCanonicalName());
            throw e;
        }catch (BuitException e){
            log.error("No s'ha pogut afegir l'ítem ({})  ",item.getClass().getCanonicalName());
            throw e;
        }
        return id;
    }

    public void eliminarItem(Item item) throws HibernateException, BuitException{
        try {
          //  gd.begin();
            gd.eliminar(item);
        }catch (HibernateException e){
            log.error("No s'ha pogut eliminar l'ítem ({})  ",item.getClass().getCanonicalName());
            throw e;
        }catch (BuitException e){
            log.error("No s'ha pogut eliminar l'ítem ({})  ",item.getClass().getCanonicalName());
            throw e;
        }
    }
    public void eliminarItem(Long  idItem) throws HibernateException, BuitException{
        try {
           // gd.begin();
            Item it=(Item)gd.llegir(Item.class, idItem);
            gd.eliminar(it);

        }catch (HibernateException e){
            log.error("No s'ha pogut eliminar l'ítem id: "+idItem+". {}",e.getLocalizedMessage());
            throw e;
        }catch (BuitException e){
            log.error("No s'ha pogut eliminar l'ítem ,id: "+idItem+". {}",e.getLocalizedMessage());
            throw e;
        }catch (NullPointerException e){
            log.error("No s'ha pogut eliminar l'ítem ,id: "+idItem+". {}",e.getLocalizedMessage());
            throw e;
        }
    }

    public void modificarItem(InterfaceItem item) throws HibernateException, BuitException{
            try {
               // gd.begin();
                gd.modificar(item);
            }catch (HibernateException e){
                log.error("No s'ha pogut modificar l'ítem ({})  ",item.getNom());
                throw e;
            }catch (BuitException e){
                log.error("No s'ha pogut modificar l'ítem ({})  ",item.getNom());
                throw e;
            }

    }
    public Item consultaItem(Long id) throws HibernateException, BuitException {
        Item it=null;
        try{
           // gd.begin();
            it=(Item)gd.llegir(Item.class, id);
        }catch(HibernateException e){
            log.error("No s'ha pogut obentir l'ítem :{}  ",String.valueOf(id));
            //throw e;

        }catch(BuitException e){
            log.error("No s'ha pogut obentir l'ítem :{}  ",String.valueOf(id));
        }
        return it;
    }

    public InterfaceItem consultaItem(Class classe ,Long id) throws HibernateException, BuitException {
        InterfaceItem it=null;
        try{
            it=(InterfaceItem)gd.llegir(classe, id);

        }catch(HibernateException e){
            log.error("No s'ha pogut obentir l'ítem :{}  ",String.valueOf(id));
            //throw e;
        }catch(BuitException e){
            log.error("No s'ha pogut obentir l'ítem :{}  ",String.valueOf(id));
            //throw e;
        }
        return it;
    }
    public Item consulta(String camp, Object valor) throws HibernateException
            , BuitException, UnsupportedEncodingException {
        Item itm=null;
        try{

            itm=(Item)gd.llegir(Item.class,camp, valor);
        }catch(HibernateException e){
            log.error("DAO:consulta: No s'ha pogut obtenir les dades segons el "
                    +"criteri:camp:"+camp+" valor:"+valor.toString());
            //throw e;

        }catch (BuitException e){
            log.info("DAO:Consulta:No s'ha pogut obtenir l`ítem. No existeix "
                    +"el login: "+String.valueOf(valor));
            throw e;
        }catch (UnsupportedEncodingException e){
            log.error("DAO:Consulta:No s'ha pogut obtenir l`ítem. Error de "+
                    "paràmetres  ");
            throw e;
        }
        return itm;
    }


    public Iterator<Item> llista()  throws HibernateException, BuitException{
        Iterator<Item> llistat =null;
        try{
            //gd.begin();
            llistat= (Iterator<Item>) gd.Llista(Item.class).iterator();
        }catch(HibernateException e){
            log.error("No s'ha pogut obentir la llista d`Ítems :{}  ",e.getLocalizedMessage());

        }catch(BuitException e){
            log.error("Llista d`items buida ",e.getLocalizedMessage());
        }
        return llistat;
    }

    public Iterator<Item> llista(String ordre, int quants)  throws HibernateException, BuitException{
        Iterator<Item> llistat =null;
        try{
            //gd.begin();
            llistat= (Iterator<Item>) gd.Llista(Item.class,ordre,quants).iterator();
        }catch (BuitException e){
            log.error("No s'ha pogut obtenir el llistat d`ítems ");
            throw e;
        }
        finally{
           // gd.close();
        }
        return llistat;
    }

    public Iterator<Item> llista(String camp, String ordre, int quants) throws HibernateException, BuitException{
        Iterator<Item> llistat =null;
        try{
            //gd.begin();
            llistat= (Iterator<Item>) gd.Llista(Item.class, 0, quants, camp, ordre).iterator();
        }catch (BuitException e){
            log.error("No s'ha pogut obtenir el llistat d`ítems ");
            throw e;
        }
        finally{
           // gd.close();
        }
        return llistat;
    }
public Iterator<Item> llista(int ini, int fi)  throws HibernateException, BuitException{
        Iterator llistat =null;
        try{
           // gd.begin();
            //llistat= gd.Llista(Contenidor.class,ini,fi);
            llistat= (Iterator<Item>) gd.Llista(Item.class, ini, fi, "nom", Config.ORDRE).iterator();
        }catch (BuitException e){
            log.error("No s'ha pogut obtenir el llistat d'ítems.",e.getLocalizedMessage());
            throw e;
        }catch(HibernateException e){
            log.error("llistat amb errors d'hibernate ({})  ",e.getLocalizedMessage());
            throw e;
        }
        finally{
           // gd.close();
        }
        return llistat;
    }

    protected Iterator<Item> llista(String camp, String cmp, Object valor,int ini, int fi)  throws HibernateException, BuitException{
        Iterator<Item> llistat =null;
        try{

            llistat= (Iterator<Item>) gd.Llista(Item.class ,camp ,cmp, valor , ini, fi, camp, Config.ORDRE).iterator();

        }catch (BuitException e){
            log.error("No s'ha pogut obtenir el llistat d`ítems .{}",e.getLocalizedMessage());
            throw e;
        }catch(HibernateException e){
            log.error("llistat amb errors d'hibernate.({})  ",e.getLocalizedMessage());
            throw e;
        }catch(NullPointerException e){
            log.error("No s'ha pogut obtenir el llistat d`ítems. algun valor null.({})  ",e.getLocalizedMessage());
            throw e;
        }finally{
           // gd.close();
        }
        return llistat;
    }



    public int quantsItems() throws HibernateException, BuitException{
         Integer quants=Config.valorNullInt;

        try {
            //gd.begin();
            quants=gd.quants( Item.class);
        }catch (HibernateException e){
            log.error("Error amb la base de dades. No s'ha pogut obtenir el nombre d'ítems.");
            throw e;
        }catch (BuitException e){
            log.error("No hi ha Ítems.");
            throw e;
        }
        return quants;
    }


     public int quantsItems(String camp, String comparacio,Object valorCercat)
            throws HibernateException, BuitException{
         Integer quants=Config.valorNullInt;
         InjeccioCodi filtre = new InjeccioCodi();

        try {
         //   gd.begin();

            quants=gd.quants( Item.class,camp,comparacio,valorCercat);
        }catch (HibernateException e){
            log.error("Error en la connexió amb la bdd. No s'ha pogut obtenir el nombre d`ítems.",e.getLocalizedMessage());

        }catch (BuitException e){
            log.error("No hi ha Ítems.{}",e.getLocalizedMessage());

        }
        return quants;
    }


    public int nombreVisites(Long id) throws NoExisteixException, BuitException{
         Integer visites=Config.valorNullInt;

        try {
           // gd.begin();
            visites=gd.nombreVisites(id, Item.class);
        }catch (HibernateException e){
            log.error("No s'ha pogut obtenir el nombre de visites.");
            throw e;
        }catch(NoExisteixException e){
            log.error("L'ítem indicat no existeix, id: {}" ,id);
            throw e;
        }catch (BuitException e){
            log.error("El nombre de visites és buit.{}",e.getLocalizedMessage());
            throw e;
        }
        return visites;
    }

    /**
     *
     * @param id, identificador
     * @return nombre de visites actualitzat
     * @throws HibernateException
     */
    public int mesVisita(Long id) throws HibernateException,NoExisteixException, BuitException{
        Integer nombreVisites=0;
        try{
            //gd.begin();
            nombreVisites=gd.augmentaVisites(id, Item.class);

        }catch (HibernateException e){
            log.error("no s'ha pogut obtenir el nombre visites ítems. Id :{}",id);
            throw e;
        }catch (NoExisteixException e){
            log.error("L'ítem indicat no existeix. Id :{}",id);
            throw e;
        }catch (BuitException e){
            log.error("nombre de visites de l`ítem buit. Id :{}",id);
            throw e;
        }


        return nombreVisites;
    }

    /*****************************************************************
     *
     * TEST
     *
     */
    private void testLlistat(ItemsDAO iDao){
        Iterator<Item> it=null;
        try{
            //it= iDao.llista();
            it= iDao.llista(Config.ORDRE, Config.nUltimsItems);
            Item item=null;
            Eines.escriu("Prova llistat ítems");
            Eines.escriu("===================");
            while (it.hasNext()){
                item=it.next();
                Eines.escriu("Dades ítem :"+item.toString());
            }
        }catch(HibernateException e){
                log.error("Error hibernate llistat");
        }catch(BuitException e){
                log.error("Error Buit llistat");
        }
        Eines.escriu("");
    }
    private void testConsulta (ItemsDAO iDao){
        Item item=null;
        try{
            item=iDao.consultaItem(1L);
            Eines.escriu("Prova consulta ítems");
            Eines.escriu("====================");
            Eines.escriu("item :"+item.toString());
        }catch(NullPointerException e){
               log.error("Error NullPointer consulta");
        }catch(BuitException e){
               log.error("Error Buit consulta");
        }
        Eines.escriu("");
    }
    private void testNombreVisites(ItemsDAO iDao){
        Long id=1L;
        Eines.escriu("Prova nombre visites item: "+id);
        Eines.escriu("==========================");
        try {
            Eines.escriu(iDao.nombreVisites(id));
        }catch(NoExisteixException e){
               log.error("Error No existeix item");
        }catch (BuitException e){
               log.error("Error Buit llistat");
        }
        Eines.escriu("");
    }
    private void testQuants(ItemsDAO iDao){
        Eines.escriu("Prova quants ítems");
        Eines.escriu("==================");
        try {
            Eines.escriu(iDao.quantsItems());
        }catch (BuitException e){
               log.error("Error Buit Quants");
        }
        Eines.escriu("");
    }

     public static void main(String args[]){
        ItemsDAO iDao = new ItemsDAO();
        try {
            //Eines.escriu(iDao.quantsItems("nom", "like", "emili"));
            Eines.escriu(iDao.quantsItems());
        } catch (HibernateException ex) {
            Logger.getLogger(ItemsDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (BuitException ex) {
            Logger.getLogger(ItemsDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
/*
        Iterator<Item> li=null;
        try {
            li = iDao.llista(0, 12);
        } catch (HibernateException ex) {
            Logger.getLogger(ItemsDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (BuitException ex) {
            Logger.getLogger(ItemsDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
        while (li.hasNext()){
            Eines.escriu(li.next().getNom());
        }*/
        iDao.tancarConnexio();

    }


}
